package com.example.su_shi_tan_core.view

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.animation.*
import android.widget.ScrollView
import androidx.interpolator.view.animation.FastOutLinearInInterpolator
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator
import com.example.su_shi_tan_core.R
import com.nineoldandroids.animation.ValueAnimator


/**
 * https://www.jianshu.com/p/8185b5bcdb9d
 * */

class HeaderScaleScrollView
@JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    ScrollView(context, attrs, defStyleAttr) {



    //需要被放大的view
    private var mZoomView: View? = null

    private var mZoomViewWidth = 0
    private var mZoomViewHeight = 0

    //记录第一次按下的位置
    private var firstPosition  = 0f

    //是否正在缩放
    private var isScrolling  = false

    //缩放系数，缩放系数越大，变化的越大
    private var mScrollRate = 0.3f

    //回调系数，越大，回调越慢
    private var mReplyRate = 0.5f


    init {
        context.obtainStyledAttributes(attrs, R.styleable.HeaderScaleScrollView).apply {
            val headerLayoutId = getResourceId(R.styleable.HeaderScaleScrollView_headerLayoutId, 0)
            inflaterDropZoomView(headerLayoutId)
        }.recycle()
    }

    private fun inflaterDropZoomView(headerLayoutId: Int) {
        if (headerLayoutId == 0) return
        mZoomView = LayoutInflater.from(context).inflate(headerLayoutId, this, false)
    }

    override fun onFinishInflate() {
        super.onFinishInflate()
        initSettings()
    }

    private fun initSettings() {
        overScrollMode = OVER_SCROLL_NEVER
        val inner = getChildAt(0)
        if (inner is ViewGroup) {
            val childView = inner as ViewGroup
            if (mZoomView == null) {
                if (childView.childCount > 0) {
                    mZoomView = childView.getChildAt(0)
                }
                return
            }
            if (childView.childCount > 0) {
                childView.addView(mZoomView, 0)
            } else {
                childView.addView(mZoomView)
            }
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (mZoomViewWidth <= 0 || mZoomViewHeight <= 0) {
            mZoomViewWidth = mZoomView?.measuredWidth ?:0
            mZoomViewHeight = mZoomView?.measuredHeight ?:0
        }

        when (ev.action) {
            MotionEvent.ACTION_UP -> {
                //手指离开后恢复图片
                isScrolling = false
                replyImage()
            }
            MotionEvent.ACTION_MOVE -> {
                if (!isScrolling) {
                    firstPosition = if (scrollY == 0) {
                        ev.y
                    } else {
                        0f
                    }
                }
                // 滚动距离乘以一个系数
                val distance =
                    ((ev.y - firstPosition) * mScrollRate).toInt()
                // 当前位置比记录位置要小，正常返回
                if (distance >= 0) {
                    // 处理放大
                    isScrolling = true
                    setZoom(distance.toFloat())
                }

            }
        }

        return super.dispatchTouchEvent(ev)
    }


    //回弹动画
    private fun replyImage() {
        val distance = ((mZoomView?.measuredWidth?:0) - mZoomViewWidth).toFloat()
        val valueAnimator: ValueAnimator =
            ValueAnimator.ofFloat(distance, 0f)
                .setDuration((distance * mReplyRate).toLong())
        valueAnimator.interpolator= OvershootInterpolator()
//        valueAnimator.repeatCount=3
        valueAnimator.addUpdateListener { animation -> setZoom(animation.animatedValue as Float) }
        valueAnimator.start()
    }

    private fun setZoom(zoom: Float) {
        if (mZoomViewWidth <= 0 || mZoomViewHeight <= 0) {
            return
        }
        val lp = mZoomView?.layoutParams
        lp?.width = (mZoomViewWidth + zoom).toInt()
        lp?.height = (mZoomViewHeight * ((mZoomViewWidth + zoom) / mZoomViewWidth)).toInt()
        (lp as MarginLayoutParams).setMargins(-(lp.width - mZoomViewWidth) / 2, 0, 0, 0)
        mZoomView?.layoutParams = lp
    }

}